{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 问题描述"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "竞赛官网：\n",
    "\n",
    "https://www.kaggle.com/c/event-recommendation-engine-challenge/data\n",
    "\n",
    "活动描述信息在events.csv文件：共110维特征\n",
    "\n",
    "前9列：event_id, user_id, start_time, city, state, zip, country, lat, and lng.\n",
    "\n",
    "event_id：活动的id, \n",
    "\n",
    "user_id：创建活动的用户的id . \n",
    "\n",
    "city, state, zip, and country： 活动地点 (如果知道的话).\n",
    "\n",
    "lat and lng： floats（活动地点的经度和纬度）\n",
    "\n",
    "start_time： 字符串，ISO-8601 UTC time，表示活动开始时间\n",
    "\n",
    "后101列为词频：count_1, count_2, ..., count_100，count_other\n",
    "\n",
    "count_N：活动描述出现第N个词的次数\n",
    "\n",
    "count_other：除了最常用的100个词之外的其余词出现的次数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 作业要求"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "根据活动的关键词（count_1, count_2, ..., count_100，count_other属性）做聚类，可采用KMeans聚类 尝试K=10，20，30，..., 100, 并计算各自CH_scores。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 解题提示"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "提示：由于样本数目较多，建议使用MiniBatchKMeans。\n",
    "\n",
    "文件说明： \n",
    "\n",
    "1. 可以先运行0. EDA.ipynb，看一下竞赛所有数据的情况；\n",
    "\n",
    "2. 总体活动的数目太多（300w+记录），可以只需对训练集train.csv和测试集test.cv出现的活动（13418条记录）举行聚类即可。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 批改标准"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 抽取出只在训练集和测试集中出现的event：20分 \n",
    "\n",
    "2. 聚类 ：40分 \n",
    "\n",
    "3. CH_scores计算：20分 \n",
    "\n",
    "4. 结果显示/分析：20分"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 1: 抽取出只在训练集和测试集中出现的 event"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.cluster import MiniBatchKMeans\n",
    "from sklearn import metrics\n",
    "\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The total events in train and test sets： 13418\n"
     ]
    }
   ],
   "source": [
    "# 读取训练集train.csv和测试集test.cv出现的活动\n",
    "\n",
    "dtrain = pd.read_csv('train.csv')\n",
    "dtest = pd.read_csv('test.csv')\n",
    "\n",
    "train_events = dtrain['event'] \n",
    "test_events = dtest['event']\n",
    "\n",
    "total_events = set(set(train_events) | set(test_events))\n",
    "total_events = list(total_events)\n",
    "\n",
    "print('The total events in train and test sets：',len(total_events))\n",
    "\n",
    "total_events = pd.DataFrame(data=total_events,columns=['event'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取文件'events.csv'\n",
    "\n",
    "devents = pd.read_csv('events.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3137972, 110)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "devents.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>event_id</th>\n",
       "      <th>c_1</th>\n",
       "      <th>c_2</th>\n",
       "      <th>c_3</th>\n",
       "      <th>c_4</th>\n",
       "      <th>c_5</th>\n",
       "      <th>c_6</th>\n",
       "      <th>c_7</th>\n",
       "      <th>c_8</th>\n",
       "      <th>c_9</th>\n",
       "      <th>...</th>\n",
       "      <th>c_92</th>\n",
       "      <th>c_93</th>\n",
       "      <th>c_94</th>\n",
       "      <th>c_95</th>\n",
       "      <th>c_96</th>\n",
       "      <th>c_97</th>\n",
       "      <th>c_98</th>\n",
       "      <th>c_99</th>\n",
       "      <th>c_100</th>\n",
       "      <th>c_other</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>684921758</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>244999119</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3928440935</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2582345152</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1051165850</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 102 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     event_id  c_1  c_2  c_3  c_4  c_5  c_6  c_7  c_8  c_9   ...     c_92  \\\n",
       "0   684921758    2    0    2    0    0    0    0    0    0   ...        0   \n",
       "1   244999119    2    0    2    0    0    0    0    0    0   ...        0   \n",
       "2  3928440935    0    0    0    0    0    0    0    0    0   ...        0   \n",
       "3  2582345152    1    0    2    1    0    0    0    0    0   ...        0   \n",
       "4  1051165850    1    1    0    0    0    0    0    2    0   ...        0   \n",
       "\n",
       "   c_93  c_94  c_95  c_96  c_97  c_98  c_99  c_100  c_other  \n",
       "0     1     0     0     0     0     0     0      0        9  \n",
       "1     0     0     0     0     0     0     0      0        7  \n",
       "2     0     0     0     0     0     0     0      0       12  \n",
       "3     0     0     0     0     0     0     0      0        8  \n",
       "4     0     0     0     0     0     0     0      0        9  \n",
       "\n",
       "[5 rows x 102 columns]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 抽取 devents 中所有列的 labels\n",
    "col_all = list(devents.columns) \n",
    "\n",
    "# 只保留列 labels： event_id, c_1, c_2, ..., c_other\n",
    "col_events = [col_all[0]]\n",
    "for i in range(9,len(col_all)):\n",
    "    col_events.append(col_all[i]) # all column labels\n",
    "\n",
    "# 从'events.csv'中抽取出只在训练集和测试集中出现的 event\n",
    "events = devents.loc[devents['event_id'].isin(total_events['event'])][col_events]\n",
    "events.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(13418, 102)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "events.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tasks 2 & 3: 对事件进行聚类和计算 CH_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将训练集合拆分成训练集和校验集\n",
    "\n",
    "y_train = events['event_id']\n",
    "X_train = events.drop('event_id',axis=1)\n",
    "X_train_part, X_val, y_train_part, y_val = train_test_split(X_train,y_train, test_size = 0.2, random_state = 28)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义一个聚类数为 K 的函数，评价聚类算法性能\n",
    "\n",
    "def K_cluster_analysis(K, X_train, y_train, X_val, y_val):     \n",
    "    mb_kmeans = MiniBatchKMeans(n_clusters = K)\n",
    "    mb_kmeans.fit(X_train)  \n",
    "    \n",
    "    # 在校验集上测试\n",
    "    y_val_pred = mb_kmeans.predict(X_val)\n",
    "    \n",
    "    # 计算 CH_score \n",
    "    #CH_score = metrics.calinski_harabaz_score(X_train,mb_kmeans.predict(X_train))\n",
    "    CH_score = metrics.silhouette_score(X_train,mb_kmeans.predict(X_train))\n",
    "    print('CH_score for K = %d: '%K, CH_score)\n",
    "    \n",
    "    # 也可以在校验集上评估 K -- 计算 v_score\n",
    "    #v_score = metrics.v_measure_score(y_val, y_val_pred)\n",
    "    #print('v_score for K = %d: '%K, v_score)\n",
    "    \n",
    "    return CH_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CH_score for K = 5:  0.50367805335658\n",
      "CH_score for K = 10:  0.3316151268360566\n",
      "CH_score for K = 20:  0.28372892166347596\n",
      "CH_score for K = 30:  0.2402493137885589\n",
      "CH_score for K = 40:  0.20913809044252146\n",
      "CH_score for K = 50:  0.12451542934383791\n",
      "CH_score for K = 60:  0.11801789394059319\n",
      "CH_score for K = 70:  0.13376106204570962\n",
      "CH_score for K = 80:  0.08323294342536466\n",
      "CH_score for K = 90:  0.06417963814501486\n",
      "CH_score for K = 100:  0.08498240451731053\n"
     ]
    }
   ],
   "source": [
    "# 设置超参数（聚类数目 K）搜索范围\n",
    "   \n",
    "Ks = [5,10,20,30,40,50,60,70,80,90,100]\n",
    "CH_scores = []\n",
    "#v_scores = []\n",
    "for K in Ks:\n",
    "    ch = K_cluster_analysis(K, X_train_part, y_train_part, X_val, y_val)\n",
    "    CH_scores.append(ch)\n",
    "    #v_scores.append(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0,0.5,'CH_scores')"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x360 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制不同聚类数目 K 下的 CH_score ,找到最佳模型／参数（分数最高）\n",
    "\n",
    "plt.figure(figsize=(6,5));\n",
    "\n",
    "# Plot of Ks v.s. CH_scores:\n",
    "#plt.subplot(121)\n",
    "plt.plot(Ks,np.array(CH_scores),'b-')\n",
    "plt.xlabel('Ks')\n",
    "plt.ylabel('CH_scores')\n",
    "\n",
    "# Plot of Ks v.s. v_scores:\n",
    "#plt.subplot(122)\n",
    "#plt.plot(Ks,np.array(v_scores),'g-')\n",
    "#plt.xlabel('Ks')\n",
    "#plt.ylabel('v_scores')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从图中看出：\n",
    "\n",
    "CH_score 的整体趋势随着聚类数目 K 的增大而减小，当聚类数 K=5 时聚类效果最好，CH_score 的值最大，为 0.5036。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Task 4: 结果显示/分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "colors = ['red','blue','black','green','yellow'] # 每一类用一种颜色 \n",
    "\n",
    "# 显示聚类数K=5时的结果\n",
    "n_clusters = 5\n",
    "mb_kmeans = MiniBatchKMeans(n_clusters = n_clusters)\n",
    "mb_kmeans.fit(X_train)\n",
    "y_train_pred = mb_kmeans.labels_ \n",
    "centers = mb_kmeans.cluster_centers_\n",
    "\n",
    "X_train = np.array(X_train)\n",
    "\n",
    "plt.figure(figsize=(8,5))\n",
    "plt.axis([0,100,0,50])\n",
    "for i in range(n_clusters):\n",
    "    index = np.nonzero(y_train_pred==i)[0]\n",
    "    x = X_train[index,0]\n",
    "    y = X_train[index,1]\n",
    "    for j in range(len(x)):\n",
    "        if j<50:\n",
    "            plt.scatter(x[j],y[j],color=colors[i],s=20)\n",
    "    plt.scatter(centers[i,0],centers[i,1],marker='x',color=colors[i],s=90)\n",
    "    \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "结果分析：\n",
    "\n",
    "聚类效果并不太好，在聚类数 K=5 时，尽管 CH-score 略大于0.5，但有些簇的点是重合在一起的，聚类效果并不好。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
